package com.api.syh56.shengyunhui.controller;


import cn.jiguang.sdk.api.DeviceApi;
import cn.jiguang.sdk.api.PushApi;
import cn.jiguang.sdk.bean.device.*;
import cn.jiguang.sdk.bean.push.PushSendParam;
import cn.jiguang.sdk.bean.push.PushSendResult;
import cn.jiguang.sdk.bean.push.audience.Audience;
import cn.jiguang.sdk.bean.push.message.notification.NotificationMessage;
import cn.jiguang.sdk.bean.push.options.Options;
import cn.jiguang.sdk.constants.ApiConstants;
import cn.jiguang.sdk.enums.platform.Platform;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dyplsapi20170525.Client;
import com.aliyun.dyplsapi20170525.models.BindAxbRequest;
import com.aliyun.oss.common.utils.StringUtils;
import com.aliyun.tea.TeaException;
import com.api.syh56.shengyunhui.common.CommonResult;

import com.api.syh56.shengyunhui.common.Constants;
import com.api.syh56.shengyunhui.entity.*;
import com.api.syh56.shengyunhui.entity.common.ApiAreaDb;
import com.api.syh56.shengyunhui.entity.vo.WAGParamVO;
import com.api.syh56.shengyunhui.exception.BaseException;
import com.api.syh56.shengyunhui.mapper.UserMapper;
import com.api.syh56.shengyunhui.mapper.WayBillMapper;
import com.api.syh56.shengyunhui.properties.JPushProperties;
import com.api.syh56.shengyunhui.properties.WechatProperties;
import com.api.syh56.shengyunhui.service.*;
import com.api.syh56.shengyunhui.util.*;
import com.api.syh56.shengyunhui.websocket.ChatServer;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;


import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.gson.Gson;


import com.google.gson.JsonObject;
import com.openapi.sdk.service.DataExchangeService;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.cipher.PrivacyEncryptor;
import com.wechat.pay.java.core.cipher.Signer;
import com.wechat.pay.java.core.http.*;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;

import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.*;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.MediaType;

import org.apache.http.entity.ContentType;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import com.wechat.pay.java.core.exception.HttpException;
import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.core.exception.ServiceException;


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import cn.jiguang.sdk.api.PushApi;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.client.RestTemplate;

import java.security.Signature;
import java.util.Base64;
import java.util.stream.Collectors;




@RestController
@RequestMapping("test")
@Slf4j
public class TestController {

    @Resource
    private UserService userService;
    @Resource
    private WayBillService wayBillService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private CouponDetService couponDetService;

    @GetMapping("get")
    private void get(@RequestParam Long wid){
        Waybill waybill = wayBillService.getById(wid);
        systemMessageService.SendMessageToDriverTimeOut(waybill);
        Integer sendTimes = waybill.getSendTimes();
        sendTimes += 1;
        waybill.setSendTimes(sendTimes);
        wayBillService.updateById(waybill);
    }

    @GetMapping("getUser")
    private CommonResult<Object> getUser(@RequestParam String company){
        List<User> users = userMapper.getUser(company);
        System.out.println(users);
        if (users.isEmpty()) {
            System.out.println("公司首次认证认证增加优惠券");
//            couponDetService.insert();
        }else{
            System.out.println("公司重复认证,只返还优惠券");
            for (User user : users){
                Integer couponNum = user.getCouponNum();
                if (couponNum != null) {
                    System.out.println("更改优惠券绑定关系");
//                    UpdateWrapper<CouponDet> wrapper = new UpdateWrapper<>();
//                    wrapper.lambda()
//                            .eq(CouponDet::getUid,user.getId())
//                            .set(CouponDet::getUid,userDB.getId());
//                    couponDetService.update(wrapper);
//                    break;
                }
            }
        }
//        ArrayList<CouponDet> couponDetsN = new ArrayList<>();
//        for (User user : users){
//            Integer couponNum = user.getCouponNum();
//            System.out.println(user.getUserName() +":"+couponNum);
//            if ( couponNum != null ) {
//                System.out.println("11111111111111111111111111111111111111111");
//                List<CouponDet> couponDets = couponDetService.updateByUid(user.getId());
//                for (CouponDet couponDet : couponDets){
//                    couponDetsN.add(couponDet);
//                }
//            }
//        }
        return CommonResult.success(null);
    }

    @Autowired
    private RSAAutoCertificateConfig rsaAutoCertificateConfig;
    @GetMapping("/slf4jTest")
    public String test1(){
        log.debug("debug测试日志消息");
        log.info("info 测试日志信息");
        log.error("info 测试日志信息");
        log.warn("warn 测试日志信息");
        return "ok";
    }

    private  HttpClient httpClient;

    @Autowired
    private PushApi pushApi;
    @Autowired
    private DeviceApi deviceApi;

   @Autowired
    private ObjectMapper objectMapper;






    public void getDevice() {
        String registrationId = "1104a89793af2cfc030";
        DeviceGetResult result = deviceApi.getDevice(registrationId);
        log.info("result:{}", result);
    }


    public void setDevice() {
        String registrationId = "1104a89793af2cfc030";
        DeviceSetParam.Tags tags = new DeviceSetParam.Tags();
        tags.setAdd(Arrays.asList("13111111111", "13222222222"));
        tags.setRemove(Arrays.asList("13333333333", "13444444444"));
        DeviceSetParam param = new DeviceSetParam();
        param.setTags(tags);
        param.setAlias("13111111111");
        param.setMobile("13111111111");
        deviceApi.setDevice(registrationId, param);
    }


    public void getAlias() {
        String alias = "13111111111";
        AliasGetResult result = deviceApi.getAlias(alias);
        log.info("result:{}", result);
    }


    public void deleteAlias() {
        String alias = "13111111111";
        deviceApi.deleteAlias(alias);
    }


    public void getTag() {
        String registrationId = "1104a89793af2cfc030";
        String tag = "13111111111";
        TagGetResult result = deviceApi.getTag(tag, registrationId);
        log.info("result:{}", result);
    }

    public void setTag() {
        String tag = "13111111111";
        TagSetParam.RegistrationIds registrationIds = new TagSetParam.RegistrationIds();
        registrationIds.setAdd(Arrays.asList("1104a89793af2cfc030", "1104a89793af2cfc030"));
        TagSetParam param = new TagSetParam();
        param.setRegistrationIds(registrationIds);
        deviceApi.setTag(tag, param);
    }


    public void deleteTag() {
        String tag = "13111111111";
        deviceApi.deleteTag(tag);
    }


    public void send(Boolean ApnsProduction,String registrationId) {

        PushSendParam param = new PushSendParam();
        // 通知内容
        NotificationMessage.Android android = new NotificationMessage.Android();
        android.setAlert("this is android alert");
        android.setTitle("this is android title");

        NotificationMessage.IOS iOS = new NotificationMessage.IOS();
        Map<String, String> iOSAlert = new HashMap<>();
        iOSAlert.put("title", "this is iOS title");
        iOSAlert.put("subtitle", "this is iOS subtitle");
        iOS.setAlert(iOSAlert);



        Map<String, Object> extrasMap = new HashMap<>();
        Map<String, Object> extrasParamMap = new HashMap<>();
        extrasParamMap.put("key1", "value1");
        extrasParamMap.put("key2", "value2");
        extrasMap.put("params", extrasParamMap);
        android.setExtras(extrasMap);
        iOS.setExtras(extrasMap);

        NotificationMessage notificationMessage = new NotificationMessage();
        notificationMessage.setAlert("this is alert");
        notificationMessage.setAndroid(android);
        notificationMessage.setIos(iOS);

        param.setNotification(notificationMessage);

        // 目标人群
        Audience audience = new Audience();
        audience.setRegistrationIdList(Arrays.asList(registrationId));

        // 指定目标
         param.setAudience(audience);

        // 或者发送所有人
//        param.setAudience(ApiConstants.Audience.ALL);

        // 指定平台
//        param.setPlatform(Arrays.asList(Platform.android, Platform.ios));

        // 或者发送所有平台
         param.setPlatform(ApiConstants.Platform.ALL);

        // Android厂商
        // param.setThirdNotificationMessage();

        // 短信补充
        // param.setSmsMessage();

        // 回调
        // param.setCallback();

        // options
        Options options = new Options();
        options.setApnsProduction(ApnsProduction);
        param.setOptions(options);
//        Map<String, Object> thirdPartyMap = new HashMap<>();
//        Map<String, Object> huaweiMap = new HashMap<>();
//        huaweiMap.put("distribution", "first_ospush");
//        huaweiMap.put("importance", "NORMAL");
//        huaweiMap.put("category", "MARKETING");
//        thirdPartyMap.put("huawei", huaweiMap);
//        options.setThirdPartyChannel(thirdPartyMap);
//        param.setOptions(options);

        // 发送
        PushSendResult result = pushApi.send(param);
        log.info("result:{}", result);
    }




    public void withdrawMessage() {
        String messageId = "18101213529672826";
        pushApi.withdrawMessage(messageId);
    }

    @Autowired
    private JpushService jpushService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private TmpAddressService tmpAddressService;
@Autowired

private QuoteService quoteService;

    @GetMapping("lists")
    public void lists(Boolean ApnsProduction,String registrationId) {

//        jpushService.pushMessageToUserId(1235L,"省运慧","这是一条测试消息");
//        send(ApnsProduction,registrationId);
        QueryWrapper<Waybill> waybillQueryWrapper = new QueryWrapper<>();
        waybillQueryWrapper.lambda().eq(Waybill::getWaybillStatus, Constants.WaybillStatus.CANCELLED);
        List<Waybill> list = wayBillService.list(waybillQueryWrapper);
        LocalDateTime now = LocalDateTime.now();
        for (Waybill waybill : list) {
            LocalDateTime creationTime = waybill.getCreationTime();
            // 判断是否超过三天
            if (creationTime.plusDays(7).isBefore(now)) {
                wayBillService.removeById(waybill);
                Long goodsId = waybill.getGoodsId();
                Long shipAddressId = waybill.getShipAddressId();
                Long receiveAddressId = waybill.getReceiveAddressId();

                if (goodsService.getById(goodsId) != null){
                    goodsService.removeById(goodsId);
                }
                if (tmpAddressService.getById(shipAddressId) != null){
                    tmpAddressService.removeById(shipAddressId);
                }
                if (tmpAddressService.getById(receiveAddressId) != null){
                    tmpAddressService.removeById(receiveAddressId);
                }
                QueryWrapper<Quote> quoteQueryWrapper = new QueryWrapper<>();
                quoteQueryWrapper.lambda().eq(Quote::getWaybillId, waybill.getId());
                quoteService.remove(quoteQueryWrapper);


                System.out.println("删除运单号"+waybill.getId());
            }
        }
    }

    @GetMapping("quoteremoveWaybill")
    public CommonResult<WAGParamVO> quoteremoveWaybill(Long wid){

//        List<Quote> list = quoteService.list();
//        for (Quote quote : list) {
//            Long waybillId = quote.getWaybillId();
//            if (wayBillService.getById(waybillId) == null){
//                quoteService.removeById(quote);
//            }
//        }
        WAGParamVO wagParamVO = wayBillService.showOneInfo(wid);
        return CommonResult.success(wagParamVO);
    }



    @Autowired
    SystemMessageService systemMessageService;



    @GetMapping("testmessage")
    public void testmessage() {

//        systemMessageService.sendSmsMessage(1824252217695842306L, "江苏省无锡市", "北京市北京城区", "已发货", "18851190812");

//        systemMessageService.sendSmsShipMessage("18851190812", "123465","江苏省无锡市", "北京市北京城区", "已发货","051085808887","苏EAF296");
//        systemMessageService.sendSmsReceiveMessage("18851190812", "123465","江苏省无锡市", "北京市北京城区", "已发货","苏EAF296");
    }

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private ApiAreaDbService apiAreaDbService;

    @Autowired
    private RoutesService routesService;




    @GetMapping(value = "test")
    public CommonResult<Object> test(@RequestParam Long start,
                                     @RequestParam Long end,
                                     @RequestParam String keywords,
                                     @RequestParam String origAddr,
                                     @RequestParam String destAddr)  {
//        System.out.println(id);
//        Waybill waybill = wayBillService.getById(id);
//        systemMessageService.SendMessageToDriverWhenSameAddress(waybill);
//        userService.addBalance(id, new BigDecimal(0.1));
//        redisUtil.set(String.valueOf(id), "123");
//
//        String res = "{\"result\":{\"address\":\"无锡惠山经济开发区前洲配套区惠澄大道1001号S5598\",\"businessScope\":\"许可项目：第一类增值电信业务，第二类增值电信业务：道路货物运输（不含危险货物），城市配送运输服务（不含危险货物）（依法须经批准的项目，经相关部门批准后方可开展经营活动，具体经营项目以审批结果为准）一般项目：网络与信息安全软件开发，信息系统运行维护服务，信息系统集成服务，信息技术咨询服务，信息咨询服务（不含许可类信息咨询服务），技术服务、技术开发、技术咨询、技术交流、技术转让、技术推广，技术推广服务，互联网安全服务：数字技术服务、科技推广和应用服务，科技中介服务，物联网技术服务；厂告制作：广告发布，广告设计、代理，企业管理，企业管理咨询，企业形象策划上市场调香9六含涉外品袋）：金荡营销带品，料荟药、装询服务，法律咨询（7含依法须律师事务所执业许可的业务厂，人力资源服务（不含职业中介活动、劳务派遣服务）：劳务服务（不含劳务派遣），基于云平台的业务外包服务：软件公售服务：生产线管理服务，国内货物运输代理，普通货物仓储服务（不含危验化字单等需许可审批的项目），装卸搬运：新能源汽车整车销售：汽车零配件批发；汽车零配件零售：消防器材销售、安防设备销售，计算机软硬件及辅助设备批发；通讯设备销售：互联网销售（除销售需要许可的商品），办公设备销售：办公设备耗材销售：电子产品销售：金属制品销售：机械设备销售；化工产品销售（不含许可委花工产品），日用品销售，建筑材料销售；成品油批发（不含危险化学品）（除依法须经批准的项目外，凭营业执照依法自主开展经营活动）\",\"businessTerm\":\"长期\",\"foundDate\":\"2021年10月12日\",\"issueDate\":\"2023年12月15日\",\"legalRepresentative\":\"李小琴\",\"name\":\"江苏物云慧信息科技有限公司\",\"registeredCapital\":\"1000万元整\",\"registrationNumber\":\"91320206MA2777TJ4X\",\"type\":\"有限责任公司（自然人独资）\"},\"status\":1001}";
//        JsonObject jsonObject = new Gson().fromJson(res, JsonObject.class);
//        JsonObject result = jsonObject.get("result").getAsJsonObject();
//        String company = result.get("name").getAsString();
//        String socialCreditCode = result.get("registrationNumber").getAsString();
//        String regAddress = result.get("address").getAsString();
//        String type = result.get("type").getAsString();
//
//        Map<String, String> resMap = new HashMap<>();
//        resMap.put("company", company);
//        resMap.put("socialCreditCode", socialCreditCode);
//        resMap.put("regAddress", regAddress);
//        return CommonResult.success(resMap);


//        String url = "https://api.syh56.com:21026/api/services/app/ShengYunHui/GetDedLines";
        String url = "https://47.100.240.178:21026/api/services/app/ShengYunHui/GetDedLines";
        Map<String, String> map = new HashMap<String, String>();
        map.put("skipCount", String.valueOf(start));
        map.put("maxResultCount", String.valueOf(end));
        map.put("keywords", keywords);
        map.put("origAddr", origAddr);
        map.put("destAddr", destAddr);
//      拼接以上参数格式为name1=value1&name2=value2
        StringBuilder queryParams = new StringBuilder();

        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (queryParams.length() > 0) {
                queryParams.append("&");
            }
            queryParams.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8))
                    .append("=")
                    .append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
        }

        String json_Str = HttpUtil.sendGet(url, queryParams.toString());
        System.out.println(json_Str);

        JSONObject jsonObject = JSONObject.parseObject(json_Str);

        System.out.println(jsonObject);


        List<DedicatedLinesC> dedicatedLinesCS = new ArrayList<>();
// 从 JSON 对象中获取 "result" 节点下的 "items" 数组
        if (jsonObject.containsKey("result")) {
            JSONObject resultObject = jsonObject.getJSONObject("result");
            if (resultObject.containsKey("items")) {
                JSONArray itemsArray = resultObject.getJSONArray("items");

                // 将 JSONArray 转换为 List<DedicatedLinesC>
                dedicatedLinesCS = itemsArray.stream()
                        .map(item -> JSONObject.parseObject(item.toString(), DedicatedLinesC.class))
                        .collect(Collectors.toList());
                // 打印结果
                System.out.println(dedicatedLinesCS);
            }
        }
        List<User> userList = new ArrayList<>();
        userList = dedicatedLinesCS.stream()
                        .map(dedicatedLinesC -> deToUser(dedicatedLinesC))
                                .collect(Collectors.toList());

        for (int i = 0; i < userList.size(); i++) {
            User user = userList.get(i);
            QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
            userQueryWrapper.lambda().eq(User::getUserName, user.getUserName());

            User one = userService.getOne(userQueryWrapper);
            if (one == null) {
                CommonUtil.setIdToNull(user);
                userService.save(user);
                System.out.println(user.getUserName()+ "保存成功");
                Long userId = user.getId();

                //level city
                DedicatedLinesC dedicatedLinesC = dedicatedLinesCS.get(i);
                String originName = dedicatedLinesC.getOriginName();
                String destName = dedicatedLinesC.getPurposeName();

                originName = getCorrectName(originName);
                destName = getCorrectName(destName);

                ApiAreaDb ori = apiAreaDbService.selectByCity(originName);
                ApiAreaDb dst = apiAreaDbService.selectByCity(destName);

                if (ori == null || dst == null) {
                    System.out.println("未找到对应城市");
                    continue;
                }

                Routes routes = new Routes();
                routes.setUid(userId);
                routes.setOriProvince("");
                routes.setOriCity(ori.getName());
                routes.setOriAdCode(Long.valueOf(ori.getAdCode()));
                routes.setDstProvince("");
                routes.setDstCity(dst.getName());
                routes.setDstAdCode(Long.valueOf(dst.getAdCode()));

                QueryWrapper<Routes> routesQueryWrapper = new QueryWrapper<>();
                routesQueryWrapper.lambda().eq(Routes::getUid, userId)
                                .eq(Routes::getOriAdCode, Long.valueOf(ori.getAdCode()))
                                .eq(Routes::getDstAdCode, Long.valueOf(dst.getAdCode()));
                if (routesService.getOne(routesQueryWrapper) == null) {
                    routesService.save(routes);
                }else {
                    System.out.println("已存在相同路线");
                }

            }else {
                System.out.println("已存在相同手机号用户");
                Long userDBId = one.getId();

                //level city
                DedicatedLinesC dedicatedLinesC = dedicatedLinesCS.get(i);
                String originName = dedicatedLinesC.getOriginName();
                String destName = dedicatedLinesC.getPurposeName();

                originName = getCorrectName(originName);
                destName = getCorrectName(destName);

                ApiAreaDb ori = apiAreaDbService.selectByCity(originName);
                ApiAreaDb dst = apiAreaDbService.selectByCity(destName);

                if (ori == null || dst == null) {
                    System.out.println("未找到对应城市");
                    continue;
                }

                Routes routes = new Routes();
                routes.setUid(userDBId);
                routes.setOriProvince("");
                routes.setOriCity(ori.getName());
                routes.setOriAdCode(Long.valueOf(ori.getAdCode()));
                routes.setDstProvince("");
                routes.setDstCity(dst.getName());
                routes.setDstAdCode(Long.valueOf(dst.getAdCode()));

                QueryWrapper<Routes> routesQueryWrapper = new QueryWrapper<>();
                routesQueryWrapper.lambda().eq(Routes::getUid, userDBId)
                        .eq(Routes::getOriAdCode, Long.valueOf(ori.getAdCode()))
                        .eq(Routes::getDstAdCode, Long.valueOf(dst.getAdCode()));
                if (routesService.getOne(routesQueryWrapper) == null) {
                    routesService.save(routes);
                }else {
                    System.out.println("已存在相同路线");
                }
            }

        }

        System.out.println(json_Str);


        return CommonResult.success(userList);
    }

    User deToUser(DedicatedLinesC dedicatedLinesC) {
        User user = new User();
        user.setCompany(dedicatedLinesC.getPartnerName());
        user.setAddress(dedicatedLinesC.getDetailedAddress());
        user.setRegAddress(dedicatedLinesC.getDetailedAddress());
        user.setUserName(dedicatedLinesC.getContactPhone());
        user.setTelephone(dedicatedLinesC.getContactPhone());
        user.setNickName(dedicatedLinesC.getContact());
        user.setTrueName(dedicatedLinesC.getContact());
        user.setRoles(Constants.Role.NONE);
        String imgUrl = dedicatedLinesC.getImgUrl();
        if(imgUrl == null || imgUrl.equals("")) {
            user.setAvatarUrl("https://syhcomm.oss-cn-beijing.aliyuncs.com/appIcon/DefaultAvatar.png");
        }else {
            user.setAvatarUrl(imgUrl);
        }
        return user;
    }


//    @GetMapping(value = "testSms")
//    public CommonResult testSms(Long driverId,String message) {
//        systemMessageService.sendSmsMessage(driverId,message);
//        return null;
//    }


    String getCorrectName(String cityName) {
        if (cityName.contains("北京")) {
            return "北京城区";
        }else if (cityName.contains("上海")) {
            return "上海城区";
        }else if (cityName.contains("天津")) {
            return "天津城区";
        }else if (cityName.contains("重庆")) {
            return "重庆城区";
        };
        return cityName;
    }

//    @GetMapping(value = "testadd")
//    public void test1(@RequestParam Long id)  {
//        userService.addBalance(id, new BigDecimal(0.1));
//    }
//
//    @GetMapping(value = "testreduce")
//    public void test2(@RequestParam Long id)  {
//        userService.reduceBalance(id, new BigDecimal(0.1));
//    }




    @Autowired
    private PayInfoService payInfoService;


    @Autowired
    private NotifyService notifyService;

    @Autowired
    private JsapiServiceExtension jsapiServiceExtension;

    @Autowired
    private RefundService refundService;

    @Autowired
    private WechatPayService wechatPayService;

    @Autowired
    private WechatProperties wechatProperties;

    @Autowired
    private RestTemplate restTemplate;


    @GetMapping(value = "/chaxunwithparams")
    public CommonResult<String> wxpay() throws Exception {

        OkHttpClient client = new OkHttpClient();



        String url = "https://api.mch.weixin.qq.com/v3/new-tax-control-fapiao/user-title";

        HttpUrl httpurl = HttpUrl.parse(url);
// 构建查询参数
        HttpUrl.Builder urlBuilder = httpurl.newBuilder();
        // 假设 fapiao_apply_id 和 scene 的值已知，这里使用示例值
        urlBuilder.addQueryParameter("fapiao_apply_id", "4200002326202407151604937742");
        urlBuilder.addQueryParameter("scene", "WITH_WECHATPAY"); // 或者 "WITHOUT_WECHATPAY"
        // 构建包含查询参数的URL
        HttpUrl urlWithParams = urlBuilder.build();

        String auth = getauth("GET", urlWithParams, "");

        // 创建请求体
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
//        okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, jsonbody);
        // 创建请求构建器
        Request request = new Request.Builder()
                .url(urlWithParams)
                .get()
                .addHeader("Authorization", auth) // 添加授权头部
                .addHeader("Content-Type","application/json")
                .addHeader("Accept","application/json")
                .build();
        System.out.println(request);


        // 发送请求并获取响应
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                System.out.println("Unexpected code " + response);
            }
            // 获取响应数据
            String responseData = response.body().string();
            // 处理响应数据
            // ...
            return CommonResult.success(responseData);
        }

    }

    @GetMapping(value = "/chaxun")
    public CommonResult<String> chaxun() throws Exception {

        OkHttpClient client = new OkHttpClient();

        String url = "https://api.mch.weixin.qq.com/v3/new-tax-control-fapiao/merchant/development-config";

        HttpUrl httpurl = HttpUrl.parse(url);


        String auth = getauth("GET", httpurl, "");

        // 创建请求体
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
//        okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, jsonbody);
        // 创建请求构建器
        Request request = new Request.Builder()
                .url(httpurl)
                .get()
                .addHeader("Authorization", auth) // 添加授权头部
                .addHeader("Content-Type","application/json")
                .addHeader("Accept","application/json")
                .build();
        System.out.println(request);


        // 发送请求并获取响应
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                System.out.println("Unexpected code " + response);
            }
            // 获取响应数据
            String responseData = response.body().string();
            // 处理响应数据
            // ...
            return CommonResult.success(responseData);
        }

    }

    @GetMapping(value = "/fapiao")
    public CommonResult<String> wxpay(@RequestBody Map<String,String> requestBody) throws Exception {

        OkHttpClient client = new OkHttpClient();

        // 创建一个 JSONObject 来构建请求体
        JSONObject jsonObject = new JSONObject();
        // 添加 "card_appid" 参数
        jsonObject.put("card_appid", wechatProperties.getAppid());
        // 添加 "card_template_information" 参数
        JSONObject cardTemplateInfoJson = new JSONObject();
        // 假设 cardTemplateInfo 对象有 get 方法来获取其属性
        cardTemplateInfoJson.put("payee_name", "省运慧"); // 收款方名称，如果提供了
        cardTemplateInfoJson.put("logo_url", "http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0"); // 卡券logo地址
        // 这里省略了其他卡券模板信息的添加...
        jsonObject.put("card_template_information", cardTemplateInfoJson);
        String jsonbody = jsonObject.toString();

        String url = "https://api.mch.weixin.qq.com/v3/new-tax-control-fapiao/card-template";
//        /v3/new-tax-control-fapiao/merchant/development-config
//        /v3/new-tax-control-fapiao/card-template
        HttpUrl httpurl = HttpUrl.parse(url);
//        String auth = getauth("POST",httpurl,jsonbody);
        String auth = getauth("POST",httpurl,jsonbody);

        // 创建请求体
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, jsonbody);
        // 创建请求构建器
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("Authorization", auth) // 添加授权头部
                .addHeader("Content-Type","application/json")
                .addHeader("Accept","application/json")
                .build();
        System.out.println(request);


        // 发送请求并获取响应
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                System.out.println("Unexpected code " + response);
            }
            // 获取响应数据
            String responseData = response.body().string();
            // 处理响应数据
            // ...
            return CommonResult.success(responseData);
        }

    }

    @GetMapping(value = "/kai")
    public CommonResult<String> kai(@RequestBody Map<String,String> requestBody) throws Exception {

        OkHttpClient client = new OkHttpClient();

        // 创建一个 JSONObject 来构建请求体
        JSONObject jsonObject = new JSONObject();
        // 添加 "card_appid" 参数
        jsonObject.put("scene", "WITH_WECHATPAY");
        jsonObject.put("fapiao_apply_id", "4200002326202407151604937742");

        // 添加 "card_template_information" 参数
        JSONObject buyer_information = new JSONObject();
        // 假设 cardTemplateInfo 对象有 get 方法来获取其属性
        buyer_information.put("type", "INDIVIDUAL"); // 收款方名称，如果提供了
        buyer_information.put("name", "杨"); // 卡券logo地址
        // 这里省略了其他卡券模板信息的添加...
        jsonObject.put("buyer_information", buyer_information);


        JSONArray fapiaoInformationArray = new JSONArray();
        // 添加 "fapiao_information" 参数
        JSONObject fapiaoInformation = new JSONObject();
        fapiaoInformation.put("fapiao_id", "123456789");
        fapiaoInformation.put("total_amount", 1);
        fapiaoInformation.put("need_list", false);
        fapiaoInformation.put("remark", "备注");

        // 添加 "items" 参数
        JSONObject item = new JSONObject();
        item.put("tax_code", "3010101020203000000");
        item.put("goods_category", "运输服务");
        item.put("goods_name", "出租汽车客运服务");
        item.put("goods_id", 1);
        item.put("specification", "A4");
        item.put("unit", "次");
        item.put("quantity", 1);
        item.put("total_amount", 1);
        item.put("tax_rate", 1300);
        item.put("tax_prefer_mark", "NO_FAVORABLE");
        item.put("discount", false);

        JSONArray items = new JSONArray();
        items.add(item);
        fapiaoInformation.put("items", items);
        fapiaoInformationArray.add(fapiaoInformation);
        jsonObject.put("fapiao_information", fapiaoInformationArray);


        String jsonbody = jsonObject.toString();

        String url = "https://api.mch.weixin.qq.com/v3/new-tax-control-fapiao/fapiao-applications";
//        /v3/new-tax-control-fapiao/merchant/development-config
//        /v3/new-tax-control-fapiao/card-template
        HttpUrl httpurl = HttpUrl.parse(url);
//        String auth = getauth("POST",httpurl,jsonbody);
        String auth = getauth("POST",httpurl,jsonbody);

        // 创建请求体
        MediaType mediaType = MediaType.parse("application/json; charset=utf-8");
        okhttp3.RequestBody body = okhttp3.RequestBody.create(mediaType, jsonbody);


        PrivacyEncryptor encryptor = rsaAutoCertificateConfig.createEncryptor();
        String wechatpaySerial = encryptor.getWechatpaySerial();
        // 创建请求构建器
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .addHeader("Authorization", auth) // 添加授权头部
                .addHeader("Content-Type","application/json")
                .addHeader("Accept","application/json")
                .addHeader("Wechatpay-Serial",wechatpaySerial)
                .build();
        System.out.println(request);


        // 发送请求并获取响应
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                System.out.println("Unexpected code " + response);
            }
            // 获取响应数据
            String responseData = response.body().string();
            // 处理响应数据
            // ...
            return CommonResult.success(responseData);
        }

    }

    private String getauth(String method, HttpUrl url, String jsonbody) throws Exception {
        Signer signer = rsaAutoCertificateConfig.createSigner();
        PrivacyEncryptor encryptor = rsaAutoCertificateConfig.createEncryptor();
        String wechatPayCertificateSerialNumber = encryptor.getWechatpaySerial();


        String schema = "WECHATPAY2-SHA256-RSA2048";
        String canonicalUrl = url.encodedPath();

        if (url.encodedQuery() != null) {
            canonicalUrl += "?" + url.encodedQuery();
        }
        String nonceStr = WXPayUtil.generateNonceStr();//随机字符串
        long timestamp = System.currentTimeMillis()/1000;
        String timestampstring = String.valueOf(timestamp);


        String message =
                method + "\n" + canonicalUrl + "\n" + timestampstring + "\n" + nonceStr + "\n" + jsonbody +"\n";
        String sign = signer.sign(message).getSign();
        System.out.println(message);


        return schema +" mchid=\"" + wechatProperties.getMerchantId() + "\","
                + "nonce_str=\"" + nonceStr + "\","
                + "timestamp=\"" + timestamp + "\","
                + "serial_no=\"" + wechatProperties.getMerchantSerialNumber() + "\","
                + "signature=\"" + sign + "\"";
    }

    private String buildMessage(String method, HttpUrl url, long timestamp, String nonceStr, String body) {
        String canonicalUrl = url.encodedPath();
        if (url.encodedQuery() != null) {
            canonicalUrl += "?" + url.encodedQuery();
        }
        return method + "\n"
                + canonicalUrl + "\n"
                + timestamp + "\n"
                + nonceStr + "\n"
                + body + "\n";
    }


    /**
     * 退款测试
     * @param waybillId
     * @return
     * @throws Exception
     */
    @RequestMapping (value = "/refundDeposit")
    public CommonResult<String> wxpayrefund(@RequestParam Long waybillId) throws Exception {

//        wechatPayService.wxpayrefund(waybillId, Constants.Role.SUPERADMIN);
        QueryWrapper<PayInfo> payInfoQueryWrapper = new QueryWrapper<>();
        payInfoQueryWrapper.lambda()
                .eq(PayInfo::getWaybillId,waybillId)
                .eq(PayInfo::getAmountType, Constants.AmountType.DEPOSIT) //运费 SHIPFEE 或定金 DEPOSIT
                .eq(PayInfo::getState, Constants.PaymentStatus.PAID);
        List<PayInfo> payInfoList = payInfoService.list(payInfoQueryWrapper);

        if(payInfoList.size()==0){
            throw new BaseException("运单未支付定金或定金已退");
        } else if (payInfoList.size() != 1) {
            throw new BaseException("运单对应定金支付信息异常");
        }

        PayInfo payInfo = payInfoList.get(0);

        BigDecimal payInfoAmount = payInfo.getAmount();
        Long payInfoAmountLONG = payInfoAmount.multiply(new BigDecimal("100")).longValue();
        try {
            CreateRequest request = new CreateRequest();


            AmountReq amount = new AmountReq();
            amount.setRefund(payInfoAmountLONG);
            amount.setTotal(payInfoAmountLONG);
            amount.setCurrency("CNY");
            request.setAmount(amount);

            request.setNotifyUrl(wechatProperties.getRefundNotifyUrl());
            request.setOutTradeNo(payInfo.getPayNum());
            //3位随机数
            String characters = "0123456789abcdefghijklmnopqrstuvwxyz";
            Random random = new Random();
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < 3; i++) {
                int index = random.nextInt(characters.length());
                sb.append(characters.charAt(index));
            }
            String randomNumeric = sb.toString();

            String OutRefundNo = payInfo.getPayNum()+randomNumeric;
            request.setOutRefundNo(OutRefundNo);
//            request.setReason();
            Refund response = refundService.create(request);

            //更新pay_info表
            payInfo.setOutRefundNo(OutRefundNo);
            payInfo.setState(Constants.PaymentStatus.REFUNDED);

            payInfoService.saveOrUpdate(payInfo);
        } catch (HttpException e) { // 发送HTTP请求失败
            // 调用e.getHttpRequest()获取请求打印日志或上报监控，更多方法见HttpException定义
        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300，例如500
            // 调用e.getResponseBody()获取返回体打印日志或上报监控，更多方法见ServiceException定义
        } catch (MalformedMessageException e) { // 服务返回成功，返回体类型不合法，或者解析返回体失败
            // 调用e.getMessage()获取信息打印日志或上报监控，更多方法见MalformedMessageException定义
        }

        return CommonResult.success("已申请退款");
    }


    /**
     * 退款测试
     * @param OutRefundNo
     * @return
     * @throws Exception
     */
    @RequestMapping (value = "/refundQuery")
    public CommonResult<Object> refundQuery(@RequestParam String OutRefundNo) throws Exception {

//        QueryWrapper<PayInfo> payInfoQueryWrapper = new QueryWrapper<>();
//        payInfoQueryWrapper.lambda()
//                .eq(PayInfo::getWaybillId,waybillId)
//                .eq(PayInfo::getAmountType, Constants.AmountType.DEPOSIT)
//                .eq(PayInfo::getState, Constants.PaymentStatus.PAID);
//        List<PayInfo> payInfoList = payInfoService.list(payInfoQueryWrapper);
//
//        if(payInfoList.size()==0){
//            throw new BaseException("运单未支付定金或定金已退");
//        } else if (payInfoList.size() != 1) {
//            throw new BaseException("运单对应定金支付信息异常");
//        }
//
//        PayInfo payInfo = payInfoList.get(0);
        QueryByOutRefundNoRequest queryByOutRefundNoRequest = new QueryByOutRefundNoRequest();
        queryByOutRefundNoRequest.setOutRefundNo(OutRefundNo);
        Refund queryByOutRefundNo = refundService.queryByOutRefundNo(queryByOutRefundNoRequest);
        return CommonResult.success(queryByOutRefundNo);
    }

    /** 一、 运输节点服务
     * 本服务提供指定介质的运输节点服务。
     * */
//    @GetMapping(value = "/carLocation")
    public CommonResult<Object> transTimeManage(@RequestParam String carNum) {
//        String res = "";
//        try {
//            Map<String, String> map = new HashMap<String, String>(3);
//            map.put("cid", "417a1452-00ff-4060-af52-f959d5b74374");
//            map.put("srt", "f073c500-412e-4fbc-a10d-fe080b28ef8c");//私钥用于 SDK 生成签名，不会在请求中传输
//            map.put("vnos", carNum); //车牌号中间无空格
//            map.put("timeNearby", "72");
//
//            System.out.println(map);
//
//
//            String url = "https://zhiyunopenapi.95155.com/save/apis/transTimeManageV3";
//            DataExchangeService des = new DataExchangeService(5000, 8000);
//            System.out.println("请求地址:"+url);
//            // 通过 https 方式调用，此方法内部会使用私钥生成签名参数 sign,私钥不会发送
//            res = des.postHttps(url, map);
//            System.out.println(map);
//
//            System.out.println("返回:"+ res);
//        } catch (Exception e) {
//            System.out.println("e:" + e.getMessage());
//        }
//        return CommonResult.success(res);

//        Map<String, Object> stringObjectMap = wayBillService.waybillCarSearch(carNum);
//        return CommonResult.success(stringObjectMap);
        return null;
    }



    /** 一、 运输节点服务
     * 本服务提供指定介质的运输节点服务。
     * */
    @GetMapping(value = "/carRouterPath")
    public CommonResult<String> carRouterPath(@RequestParam String carNum,
                                              @RequestParam String color) {
        try {
            Map<String, String> map = new HashMap<String, String>(3);
            map.put("cid", "417a1452-00ff-4060-af52-f959d5b74374");
            map.put("srt", "f073c500-412e-4fbc-a10d-fe080b28ef8c");//私钥用于 SDK 生成签名，不会在请求中传输
            map.put("vclN",carNum);
            map.put("vco", color); //车牌颜色(1 蓝色、2 黄色、3 黄绿色)
            LocalDateTime now = LocalDateTime.now();
            String qryEtm = now.format(Constants.DateTimeFormatterType.ISO8601);
            String qryBtm = now.minusHours(72L).format(Constants.DateTimeFormatterType.ISO8601);

            map.put("qryBtm",qryBtm);
            map.put("qryEtm",qryEtm);

            map.put("parkMins", "30");
            String url = "https://zhiyunopenapi.95155.com/save/apis/routerPath";
            DataExchangeService des = new DataExchangeService(5000, 8000);
            System.out.println("请求地址:"+url);
            // 通过 https 方式调用，此方法内部会使用私钥生成签名参数 sign,私钥不会发送
            String res = des.postHttps(url, map);
            System.out.println("返回:"+ res);
        } catch (Exception e) {
            System.out.println("e:" + e.getMessage());
        }
        return null;
    }

    @Autowired
    private Client client;

    @GetMapping(value = "/yinsi")
    public CommonResult<String> yinsi(@RequestParam String carNum,
                                              @RequestParam String color) {


        BindAxbRequest bindAxbRequest = new BindAxbRequest();
//        bindAxbRequest.setPoolKey();
//        bindAxbRequest.setPhoneNoA();
//        bindAxbRequest.setPhoneNoB();
//        bindAxbRequest.setPhoneNoX();
//        bindAxbRequest.setExpiration();
//        bindAxbRequest.setOutOrderId();
//        bindAxbRequest.setExpectCity();

        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            client.bindAxbWithOptions(bindAxbRequest, runtime);
        } catch (TeaException error) {
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        }
        return null;
    }

    @Autowired
    private ChatServer chatServer;
    @GetMapping(value = "/webSocket")
    public CommonResult<String> webSocket() {
        chatServer.onMessage("message");
        return CommonResult.success("webSocket");

    }



}
